home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
risc_src.lha
/
risc_sources
/
sys
/
risc_dispatch.t
< prev
next >
Wrap
Text File
|
1989-06-30
|
11KB
|
310 lines
(herald risc_dispatch (env tsys))
(define (dispatch-init)
(lap (handle-stype handle-true handle-fixnum handle-pair
handle-char handle-nonvalue *handlers* icall-wrong-nargs
bogus-return bogus-return-miss apply handle-immediate
handle-magic-frame no-default-method)
(move link-reg a1) ;movea kills this
(store l p (d@nil slink/dispatch))
(movea dispatch extra)
(store l extra (d@nil slink/dispatch-label))
(jr a1)
(move ($ -1) nargs)))
(define *magic-frame-template*
(lap-template (4 -1 t stack magic-frame-handler)
(load l (d@r sp 16) link-reg)
(jr link-reg)
(add ($ 20) sp)
magic-frame-handler
(load l (d@nil slink/dispatch) AN)
(load l (d@r AN (static handle-magic-frame)) A1)
(load l (d@r a1 2) a1)
(jbr dispatch)))
(define *structure-template*
(lap-template (0 1 nil heap structure-handler)
(load l (d@nil slink/undefined-effect) extra)
(jr extra)
(noop)
structure-handler
(load l (d@r A1 -2) A1) ; internal-template
(load l (d@r A1 -30) A1) ; stype-handler
(jbr dispatch)))
(define *stype-template*
(lap-template (9 1 nil heap stype-handler) ; stype size is 9
(load l (d@nil slink/undefined-effect) extra)
(jr extra)
(noop)
stype-handler
(load l (d@nil slink/dispatch) AN)
(load l (d@r AN (static handle-stype)) A1)
(load l (d@r a1 2) a1)
(jbr dispatch)))
(define *traced-op-template*
(lap-template (0 1 nil heap t-op)
(sub ($ 20) sp)
(store l link-reg (d@r sp 16))
(store l A1 (d@r sp 12)) ; self
(store l nil-reg (d@r sp 8))
(store l P (d@r sp 4)) ; op
(store l A1 (d@r sp 0)) ; obj
(jl dispatch)
(add ($ template-return-offset) link-reg)
(template 4 -1 t)
(load l (d@r sp 16) link-reg)
(j= AN nil-reg traced-op-default) ; did we get a method?
; AN contains code
(move A1 P) ; environment
(load l (d@r SP 12) A1) ; self is first arg of method
(load l (d@r sp 0) AN+1) ;obj
(jbr op-icall)
traced-op-default
(load l (d@r P 6) P) ; rhs is operation
(jbr default)))
;;; We have the operation in P, the object in A1 and we can use AN which is
;;; where the method id returned
(define *operation-template*
(lap-template (3 1 t heap operation-handler)
(sub ($ 20) sp)
(store l link-reg (d@r sp 16))
(store l A1 (d@r sp 12)) ; self
(store l nil-reg (d@r sp 8))
(store l P (d@r sp 4)) ; op
(store l A1 (d@r sp 0)) ; obj
(jl dispatch)
(add ($ template-return-offset) link-reg)
(template 4 -1 t)
(load l (d@r sp 16) link-reg) ;dispatch return
(j= AN nil-reg default) ; did we get a method?
(move A1 P)
(load l (d@r SP 12) A1) ; self is first arg of method
(load l (d@r sp 0) AN+1) ;obj
op-icall
(load sb (d@r AN (- template/nargs 2)) vector) ;handler added this 2
(j= NARGS vector %icall-ok) ; check number of args
(j< nargs vector %icall-wrong-nargs)
(load ub (d@r an (- template/header 2)) vector)
(jn= vector ($ (fx+ header/template 128)) %icall-wrong-nargs)
%icall-ok
(jr an) ;handler gives code address (tp - 2)
(add ($ 20) sp)
%icall-wrong-nargs
(load l (d@r SP 4) p)
(store l p (d@nil slink/p)) ; operation
(load l (d@nil slink/dispatch) P)
(load l (d@r P (static icall-wrong-nargs)) P)
(load l (d@r p 2) p)
(load l (d@r P -2) extra)
(add ($ 2) extra)
(jr extra)
(add ($ 20) SP)
default
(load l (d@r SP 12) A1) ; self is first arg of method
(load l (d@r P offset/operation-default) P)
(j= p nil-reg no-default)
(load l (d@nil slink/icall) extra)
(jr extra)
(add ($ 20) SP)
no-default
(load l (d@r SP 4) p) ; operation
(store l p (d@nil slink/p))
(load l (d@nil slink/dispatch) P)
(load l (d@r P (static no-default-method)) P)
(load l (d@r p 2) p)
(load l (d@r P -2) extra)
(add ($ 2) extra)
(jr extra)
(add ($ 20) SP)
dispatch
(mask ($ 3) A1 vector) ; get object tag
(jn= vector ($ tag/extend) object-not-extend) ; is it an extend?
(load l (d@r A1 -2) extra) ; get object's header
(mask ($ 3) extra vector) ; is it a template?
(jn= vector ($ tag/extend) object-not-closure)
(load ub (d@r extra template/nargs) vector)
(j= zero vector cit) ; closure internal template?
(load sw (d@r extra template/handler) vector) ; get handler offset
(j= zero vector no-handler) ; it it's 0, no handler
(add extra vector)
(jr vector) ; call the handler
(noop)
no-handler
(jr link-reg)
(move nil-reg AN)
cit
(load l (d@r extra 2) AN) ; get auxilliary template
(load sw (d@r AN template/handler) vector) ; get handler offset
(j= zero vector no-handler)
(add an vector)
(jr vector)
(noop)
object-not-extend
(load l (d@nil slink/dispatch) AN) ; establish addressability
(j= vector ($ tag/fixnum) fixnum)
(j= vector ($ tag/pair) pair)
(j= a1 t-reg true)
(mask ($ #xff) a1 vector)
(j= vector ($ header/char) char)
(j= vector ($ header/nonvalue) nonvalue)
(load l (d@r AN (static handle-immediate)) A1)
(load l(d@r a1 2) a1)
(jbr dispatch)
true
(load l (d@r AN (static handle-true)) A1)
(load l (d@r a1 2) a1)
(jbr dispatch)
nonvalue
(load l (d@r AN (static handle-nonvalue)) A1)
(load l (d@r a1 2) a1)
(jbr dispatch)
fixnum
(load l (d@r AN (static handle-fixnum)) A1)
(load l (d@r a1 2) a1)
(jbr dispatch)
pair
(load l (d@r AN (static handle-pair)) A1)
(load l (d@r a1 2) a1)
(jbr dispatch)
char
(load l (d@r AN (static handle-char)) A1)
(load l (d@r a1 2) a1)
(jbr dispatch)
object-not-closure
(j= vector zero frame-op)
(load l (d@nil slink/dispatch) AN)
(load l (d@r AN (static *handlers*)) AN)
(load l (d@r an 2) an)
(mask ($ #x7c) extra vector) ; isolate low seven bits
(add an vector)
(load l (d@r vector 2) a1) ; index into vector of handlers
(jbr dispatch)
frame-op
(sub ($ 2) extra) ;coerce to template
(load sw (d@r extra template/handler) vector) ; get handler offset
(j= zero vector no-handler) ; it it's 0, no handler
(add extra vector)
(jr vector) ; call the handler
(noop)
operation-handler
(load l (d@r A1 offset/operation-handler) A1)
(jbr dispatch)))
;;; At the top of the join loop the stack looks like self
;;; next
;;; op
;;; obj
;;; sp -> dispatch-return
(define *join-template*
(lap-template (2 1 t heap join-handler)
join-template
(load l (d@r P 2) P) ; joined lhs
(load l (d@nil slink/icall) extra)
(jr extra)
(noop)
join-handler
(sub ($ 4) sp)
(store l link-reg (d@r sp 0))
(load l (d@r A1 6) extra)
(store l extra (d@r SP 12)) ; next <- rhs
(load l (d@r A1 2) A1) ; get joined lhs
(store l A1 (d@r SP 4)) ; obj <- lhs
(jl dispatch)
(add ($ template-return-offset) link-reg) ; try to get a handler from lhs
(template 0 -1 t)
join-return
(load l (d@r sp 0) link-reg)
(j= AN nil-reg join-miss) ; did we get a handler?
(jr link-reg)
(add ($ 4) sp)
join-miss
(load l (d@r SP 12) A1) ; get next
(store l A1 (d@r SP 4)) ; obj <- next
(store l nil-reg (d@r SP 12)) ; next <- tbsh
(add ($ 4) sp)
(jbr dispatch))) ; try rhs
(define *bogus-entity-template*
(lap-template (2 1 t heap bogus-entity-handler)
(load l (d@r P 2) P)
(load l (d@nil slink/icall) extra)
(jr extra)
(noop)
bogus-entity-handler
(sub ($ 8) sp)
(store l link-reg (d@r sp 4))
(store l p (d@r sp 0)) ;save p
(move A1 AN) ;temp
(move P A1) ; operation is argument to handler
(load l (d@r AN 6) p) ; bogus-entity handler
(load l (d@nil slink/icall) extra)
(jalr extra)
(add ($ template-return-offset) link-reg)
(template 1 -3 nil) ;return method and args
(jn= A1 nil-reg bogus-return-hit)
(load l (d@nil slink/dispatch) AN)
(move a2 a3) ;args
(load l (d@r AN (static bogus-return-miss)) A1) ;A2 has dummy value
(load l (d@r a1 2) a1)
(load l (d@r AN (static apply)) P)
(load l (d@r p 2) p)
(load l (d@r P -2) extra)
(add ($ 2) extra)
(jr extra)
(move ($ 4) nargs)
bogus-return-hit
(load l (d@nil slink/dispatch) AN)
(move a2 a4) ; args
(move A1 A2) ; method
(load l (d@r AN (static bogus-return)) A1)
(load l (d@r a1 2) a1)
(load l (d@r AN (static apply)) P)
(load l (d@r p 2) p)
(load l (d@r P -2) extra)
(add ($ 2) extra)
(jr extra)
(move ($ 5) NARGS) ; dummy obj in a3
bogus-return-handler
(jr link-reg)
(move nil-reg AN)))
(define (bogus-return-miss method . args)
(lap ()
(move nil-reg AN) ; compiled handlers return register
(load l (d@r sp 0) p)
(load l (d@r sp 4) link-reg)
(jr link-reg)
(add ($ 8) SP)))
(define (bogus-return method obj . args)
(lap ()
(move A1 P) ; method in procedure register
(movea join-return A1) ; is a join return address on top?
(load l (d@r sp 4) link-reg)
(add ($ 8) sp)
(jn= a1 link-reg bogus-dispatch-return)
(add ($ 4) SP) ; pop join return addr
bogus-dispatch-return
(load l (d@r sp 16) link-reg)
(load l (d@r SP 12) A1) ; self is first of interpreted method
(load l (d@r SP 0) A2) ; obj is second of interpreted method
(load l (d@nil slink/icall) extra)
(jr extra)
(add ($ 20) SP)))
(dispatch-init)